﻿using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace VMExplorer.Win32
{
	// Executable format
	partial class Native
	{
		#region :: Enums ::

		[Flags]
		public enum ImageFileCharacteristics : ushort
		{
			RELOCS_STRIPPED = 0x0001,  // Relocation info stripped from file.
			EXECUTABLE_IMAGE = 0x0002,  // File is executable  (i.e. no unresolved externel references).
			LINE_NUMS_STRIPPED = 0x0004,  // Line nunbers stripped from file.
			LOCAL_SYMS_STRIPPED = 0x0008,  // Local symbols stripped from file.
			AGGRESIVE_WS_TRIM = 0x0010,  // Agressively trim working set
			LARGE_ADDRESS_AWARE = 0x0020,  // App can handle >2gb addresses
			BYTES_REVERSED_LO = 0x0080,  // Bytes of machine word are reversed.
			x32BIT_MACHINE = 0x0100,  // 32 bit word machine.
			DEBUG_STRIPPED = 0x0200,  // Debugging info stripped from file in .DBG file
			REMOVABLE_RUN_FROM_SWAP = 0x0400,  // If Image is on removable media, copy and run from the swap file.
			NET_RUN_FROM_SWAP = 0x0800,  // If Image is on Net, copy and run from the swap file.
			SYSTEM = 0x1000,  // System File.
			DLL = 0x2000,  // File is a DLL.
			UP_SYSTEM_ONLY = 0x4000,  // File should only be run on a UP machine
			BYTES_REVERSED_HI = 0x8000,  // Bytes of machine word are reversed.
		};

		public enum ImageFileMachine : ushort
		{
			UNKNOWN = 0x0,
			I386 = 0x014c,  // Intel 386.
			R3000 = 0x0162,  // MIPS little-endian, = 0x160 big-endian
			R4000 = 0x0166,  // MIPS little-endian
			R10000 = 0x0168,  // MIPS little-endian
			WCEMIPSV2 = 0x0169,  // MIPS little-endian WCE v2
			ALPHA = 0x0184,  // Alpha_AXP
			SH3 = 0x01a2,  // SH3 little-endian
			SH3DSP = 0x01a3,
			SH3E = 0x01a4,  // SH3E little-endian
			SH4 = 0x01a6,  // SH4 little-endian
			SH5 = 0x01a8,  // SH5
			ARM = 0x01c0,  // ARM Little-Endian
			THUMB = 0x01c2,
			AM33 = 0x01d3,
			POWERPC = 0x01F0,  // IBM PowerPC Little-Endian
			POWERPCFP = 0x01f1,
			IA64 = 0x0200,  // Intel 64
			MIPS16 = 0x0266,  // MIPS
			ALPHA64 = 0x0284,  // ALPHA64
			MIPSFPU = 0x0366,  // MIPS
			MIPSFPU16 = 0x0466,  // MIPS
			AXP64 = ALPHA64,
			TRICORE = 0x0520,  // Infineon
			CEF = 0x0CEF,
			EBC = 0x0EBC,  // EFI Byte Code
			AMD64 = 0x8664,  // AMD64 (K8)
			M32R = 0x9041,  // M32R little-endian
			CEE = 0xC0EE
		};

		public enum ImageSubsytem : ushort
		{
			UNKNOWN = 0,   // Unknown subsystem.
			NATIVE = 1,   // Image doesn't require a subsystem.
			WINDOWS_GUI = 2,   // Image runs in the Windows GUI subsystem.
			WINDOWS_CUI = 3,   // Image runs in the Windows character subsystem.
			OS2_CUI = 5,   // image runs in the OS/2 character subsystem.
			POSIX_CUI = 7,   // image runs in the Posix character subsystem.
			NATIVE_WINDOWS = 8,   // image is a native Win9x driver.
			WINDOWS_CE_GUI = 9,   // Image runs in the Windows CE subsystem.
			EFI_APPLICATION = 10,  //
			EFI_BOOT_SERVICE_DRIVER = 11,   //
			EFI_RUNTIME_DRIVER = 12,  //
			EFI_ROM = 13,
			XBOX = 14,
			WINDOWS_BOOT_APPLICATION = 16
		};

		[Flags]
		public enum DllCharacteristics : ushort
		{
			PROCESS_INIT = 0x0001,     // Reserved.
			PROCESS_TERM = 0x0002,     // Reserved.
			THREAD_INIT = 0x0004,     // Reserved.
			THREAD_TERM = 0x0008,     // Reserved.
			DYNAMIC_BASE = 0x0040,     // DLL can move.
			FORCE_INTEGRITY = 0x0080,     // Code Integrity Image
			NX_COMPAT = 0x0100,     // Image is NX compatible
			NO_ISOLATION = 0x0200,     // Image understands isolation and doesn't want it
			NO_SEH = 0x0400,     // Image does not use SEH.  No SE handler may reside in this image
			NO_BIND = 0x0800,     // Do not bind this image.
			WDM_DRIVER = 0x2000,     // Driver uses WDM model
			TERMINAL_SERVER_AWARE = 0x8000
		};

		#endregion
		#region :: Structs ::

		[StructLayout (LayoutKind.Sequential, Size = 0x40)]
		public struct IMAGE_DOS_HEADER
		{
			[Description ("Magic number")]
			public UInt16   Magic;
			[Description ("Bytes on last page of file")]
			public UInt16   BytesOnLastPage;
			[Description ("Pages in file")]
			public UInt16   Pages;
			[Description ("Relocations")]
			public UInt16   Relocations;
			[Description ("Size of header in paragraphs")]
			public UInt16   HeaderSize;
			[Description ("Minimum extra paragraphs needed")]
			public UInt16   MinExtraParagraphs;
			[Description ("Maximum extra paragraphs needed")]
			public UInt16   MaxExtraParagraphs;
			[Description ("Initial (relative) SS value")]
			public UInt16   InitialSS;
			[Description ("Initial SP value")]
			public UInt16   InitialSP;
			[Description ("Checksum")]
			public UInt16   CheckSum;
			[Description ("Initial IP value")]
			public UInt16   InitialIP;
			[Description ("Initial (relative) CS value")]
			public UInt16   InitialCS;
			[Description ("File address of relocation table")]
			public UInt16   RelocTable; 
			[Description ("Overlay number")]
			public UInt16   OverlayNumber;
			[Description ("Reserved public UInt16s")]
			[MarshalAs (UnmanagedType.ByValArray, SizeConst = 4)]
			public UInt16[] Reserved1;
			[Description ("OEM identifier (for OemInfo)")]
			public UInt16   OemId;
			[Description ("OEM information; OemId specific")]
			public UInt16   OemInfo;
			[Description ("Reserved public UInt16s")]
			[MarshalAs (UnmanagedType.ByValArray, SizeConst = 10)]
			public UInt16[] Reserved2;
			[Description ("File address of new exe header")]
			public UInt32   NewHeaderOffset;
		};

		[StructLayout (LayoutKind.Sequential, Size = 0x14)]
		public struct IMAGE_FILE_HEADER
		{
			public ImageFileMachine Machine;
			public UInt16   NumberOfSections;
			public UInt32   TimeDateStamp;
			public IntPtr   PointerToSymbolTable;
			public UInt32   NumberOfSymbols;
			public UInt16   SizeOfOptionalHeader;
			public ImageFileCharacteristics Characteristics;
		};

		[StructLayout (LayoutKind.Sequential, Size = 0xE0)]
		public struct IMAGE_OPTIONAL_HEADER
		{
			//
			// Standard fields.
			//

			public UInt16   Magic;
			public Byte     MajorLinkerVersion;
			public Byte     MinorLinkerVersion;
			public UInt32   SizeOfCode;
			public UInt32   SizeOfInitializedData;
			public UInt32   SizeOfUninitializedData;
      public IntPtr AddressOfEntryPoint;
      public IntPtr BaseOfCode;
      public IntPtr BaseOfData;

			//
			// NT additional fields.
			//

      public IntPtr ImageBase;
			public UInt32   SectionAlignment;
			public UInt32   FileAlignment;
			public UInt16   MajorOperatingSystemVersion;
			public UInt16   MinorOperatingSystemVersion;
			public UInt16   MajorImageVersion;
			public UInt16   MinorImageVersion;
			public UInt16   MajorSubsystemVersion;
			public UInt16   MinorSubsystemVersion;
			public UInt32   Win32VersionValue;
			public UInt32   SizeOfImage;
			public UInt32   SizeOfHeaders;
			public UInt32   CheckSum;
			public ImageSubsytem Subsystem;
			public DllCharacteristics DllCharacteristics;
			public UInt32   SizeOfStackReserve;
			public UInt32   SizeOfStackCommit;
			public UInt32   SizeOfHeapReserve;
			public UInt32   SizeOfHeapCommit;
			public UInt32   LoaderFlags;
			public UInt32   NumberOfRvaAndSizes;

      [Description("Export Directory")]
			public IMAGE_DATA_DIRECTORY DataDirectoryExport;
      [Description ("Import Directory")]
      public IMAGE_DATA_DIRECTORY DataDirectoryImport;
      [Description ("Resource Directory")]
      public IMAGE_DATA_DIRECTORY DataDirectoryResource;
      [Description ("Exception Directory")]
      public IMAGE_DATA_DIRECTORY DataDirectoryException;
      [Description ("Security Directory")]
      public IMAGE_DATA_DIRECTORY DataDirectorySecurity;
      [Description ("Base Relocation Table")]
      public IMAGE_DATA_DIRECTORY DataDirectoryBaseReloc;
      [Description ("Debug Directory")]
      public IMAGE_DATA_DIRECTORY DataDirectoryDebug;
      [Description ("(X86 usage)")]
      public IMAGE_DATA_DIRECTORY DataDirectoryCopyright;
      [Description ("Architecture Specific Data")]
      public IMAGE_DATA_DIRECTORY DataDirectoryArchitecure; 
      [Description ("RVA of GP")]
      public IMAGE_DATA_DIRECTORY DataDirectoryGlobalPtr; 
      [Description ("TLS Directory")]
      public IMAGE_DATA_DIRECTORY DataDirectoryTLS;
      [Description ("Load Configuration Directory")]
      public IMAGE_DATA_DIRECTORY DataDirectoryLoadConfig;
      [Description ("Bound Import Directory in headers")]
      public IMAGE_DATA_DIRECTORY DataDirectoryBoundImport;
      [Description ("Import Address Table")]
      public IMAGE_DATA_DIRECTORY DataDirectoryIAT;
      [Description ("Delay Load Import Descriptors")]
      public IMAGE_DATA_DIRECTORY DataDirectoryDelayImport;
      [Description ("COM Runtime Descriptor")]
      public IMAGE_DATA_DIRECTORY DataDirectoryComDescriptor;
		};

		[StructLayout (LayoutKind.Sequential, Size = 0xF8)]
		public struct IMAGE_NT_HEADERS
		{
			public UInt32 Signature;
			public IMAGE_FILE_HEADER FileHeader;
			public IMAGE_OPTIONAL_HEADER OptionalHeader;
		};

		[StructLayout (LayoutKind.Sequential, Size = 0x08)]
		public struct IMAGE_DATA_DIRECTORY
		{
			public IntPtr   VirtualAddress;
			public UInt32   Size;
		};

		[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)]
		public struct IMAGE_SECTION_HEADER
		{
			[MarshalAs (UnmanagedType.ByValTStr, SizeConst = 8)]
			public string Name;
			public UInt32 VirtualSize;
			public UInt32 VirtualAddress;
			public UInt32 SizeOfRawData;
			public UInt32 PointerToRawData;
			public UInt32 PointerToRelocations;
			public UInt32 PointerToLinenumbers;
			public UInt16 NumberOfRelocations;
			public UInt16 NumberOfLinenumbers;
			public UInt32 Characteristics;
		};

		#endregion
		#region :: API ::
		#endregion
	}
}